/* ==========================================================================================
　global変数
========================================================================================== */
var maxView = 30;
var loadNo = 0;
var errorCounter = 0;
var nowViewCategory = "お気に入り";
var timer;
var rsaTime;

/* itemData
itemData.LVID = Array();
itemData.LVID.pubdate = date形式 開始日時
itemData.LVID.category = カテゴリー,カテゴリー,
itemData.LVID.community_id = コミュニティID
itemData.LVID.type = コミュニティ放送(co)／チャンネル放送(ch)
itemData.LVID.owner_name = 配信者名
itemData.LVID.title = 放送タイトル
*/
var itemData = new Array();


/* categoryList
categoryList["一般"] = lv000000,lv000000,lv000000,lv000000,
*/
var categoryList = new Array();



/* ==========================================================================================
　初期設定
========================================================================================== */

function farstSetup(){
    
    if( window.widget ){
        if ( widget.preferenceForKey("fv_community") == undefined) {
            widget.setPreferenceForKey( "【】Apple/Macintosh放送局 ( co8837 )\nclub rawegg ( co14594 )\n恥さらしのMacでGEEKなコミュ ( co8681 )\nMacで放送してみる ( co9414 )", "fv_community" );
        }
    }
    
    loadAllTab();
    setTabAction();
    
    $("#leftNavi li.leftNavi_Row:eq(1)").addClass("now");
    
}



/* ==========================================================================================
　メインプログラム
RSS収集、HTMLへの表示
========================================================================================== */


// 
// Function : loadAllTab()
// 全てのタブ(カテゴリ)のデータを読み込み開始します。
// 

function loadAllTab(){
    
    getXML('',1);
    
    lastUpdated = (new Date).getTime();
    if( timer ){ clearTimeout(timer) }
    timer = setTimeout(function(){loadAllTab();}, 60000 );
    
    atTimeUpdate();
    oldDelete();
}



// 
// Function : getXML(tab,pageNo)
// 指定されたRSS情報を収集実行します。
// 
// tab : common や、 r18 などのRSSのtabパラメーター
// pageNo : RSSのページ番号
// 

function getXML(tab,pageNo){
    
    try{
        $.ajax({
            url: 'http://live.nicovideo.jp/recent/rss?tab='+tab+'&sort=start&p='+pageNo,
            type: 'GET',
            dataType: "text/xml",
            timeout: 3000,
            
            success: function(data){
                var xml;
                if (typeof data == "string") {
                    var obj = new DOMParser();
                    xml = obj.parseFromString(data, "text/xml");
                } else {
                    xml = data;
                }
                
                errorCounter = 0; //正常に読み込めたのでエラーカウンターをリセット
                checkRSS(xml,tab,pageNo);
            },
            
            error: function(XMLHttpRequest, textStatus, errorThrown){
                
                if ( errorCounter > 10 ){
                    console.warn("通信エラーが10回以上発生したため、60秒間停止します。("+errorCounter+")");
                    setTimeout(function(){getXML(tab,pageNo)},60000);
                }else{
                    errorCounter++;
                    setTimeout(function(){getXML(tab,pageNo)},5000);
                }
                
            }
            
        });
    }catch(e){
                
        if ( errorCounter > 10 ){
            console.warn("通信エラーが10回以上発生したため、60秒間停止します。("+errorCounter+")");
            setTimeout(function(){getXML(tab,pageNo)},60000);
        }else{
            errorCounter++;
            setTimeout(function(){getXML(tab,pageNo)},5000);
        }
        
    }
}



//
// Function : checkRSS(xml,tab,pageNo)
// XMLオブジェクト内のデータをチェックし、次のページを表示するか否かなどのチェックを行います。
// 
// xml : jQuery.ajaxで取得したXMLオブジェクト
// tab : RSSのtabパラメーター
// pageNo : RSSのページ番号
// 

function checkRSS(xml,tab,pageNo){
    if ( $(xml).find('item').length > 0 ){ // レコード数のチェック 0の場合は終了
        
        // 既に表示済みか否かをチェック
        var farstID = $(xml).find('item:first guid').text();
        var lastID = $(xml).find('item:last guid').text();
        
        var farst = itemData[farstID];
        var last = itemData[lastID];
        if( (farst != undefined ) && (last != undefined ) ){
            
            //console.debug(tab+" : 全ての放送が既に読み込みでした。");
            //console.debug(tab+":"+farstID+"と"+tab+":"+lastID+"が既に表示済みです。");
            
        }else{
            
            // HTML上への表示実行
            //console.debug( tab+" "+pageNo+" length : "+$(xml).find('item').length );
            checkRow(xml);
            
            // 次のページ読み込み
            pageNo++;
            setTimeout(function(){getXML(tab,pageNo)},3000);
            
        }
        
    }else{
        
        //console.debug(tab+" : 最後のページまで読み込まれました。");
        
    }
}



// 
// Function : checkRow(xml)
// xmlデータ内の各レコードが表示済みか否かの確認と、記録のチェックを行います。
// 
// xml : xmlオブジェクト
// 

function checkRow(xml){
    
    $(xml).find('item').each(function(){
        
        var guid = $(this).find("guid").text();
        
        if( itemData[guid] == undefined ){ // 表示済みの放送はスキップ
            
            //表示済みとして記録
            itemData[guid] = new Array();
            
            //実際のHTML表示の実行
            createRow(this);
            
        }
         
    });
    
}



// 
// Function : createRow(xml)
// Growlへ通知する必要があるかのチェックを行います。
// xmlオブジェクトを実際にデータの分解、DOMオブジェクトの生成を行います。
// 
// xml : xmlオブジェクト
// 

function createRow(xml){
    
    // XMLの分解
    var guid = $(xml).find("guid").text();
    var title = $(xml).find("title").text();
    var link = $(xml).find("link").text();
    var pubdate = $(xml).find("pubDate").text();
    var description = $(xml).find("description").text();
    var thumbnail = $(xml).find("media:thumbnail").text();
    var author = $(xml).find("author").text();
    var community_name = $(xml).find("community_name").text();
    var community_id = $(xml).find("community_id").text();
    var num_res = $(xml).find("num_res").text();
    var view = $(xml).find("view").text();
    var member_only = $(xml).find("member_only").text();
    var owner_name = $(xml).find("owner_name").text();
    var type = $(xml).find("type").text();
    

    //通知チェック
    var fv;
    var rObj = new RegExp("\\b"+community_id+"\\b","i");
    if ( window.widget && widget.preferenceForKey("fv_community").search(rObj) != -1 ){
        categoryList["お気に入り"] += ","+guid;  //グローバル変数
        
        growlPost( title, description );
        
        fv = 1;
    }
    
    // カテゴリ別放送リストに登録
    var category = ""; //カテゴリを,区切りで記録
    var thisRowView = ""; //現在のカテゴリを表示すべきか否か
    
    
    $(xml).find("category").each(function(){
    	var name = $(this).text();
    	var colon = "";
    	if ( category != "" ){ colon = ", "; }
        category += colon+name;            //ローカル変数
        categoryList[name] += ","+guid;  //グローバル変数
        
        if ( nowViewCategory == name ||
             nowViewCategory == "すべて" ||
             ( nowViewCategory == "お気に入り" && fv == 1 )
        ){
        	thisRowView = 1;
        }
    })
    
    // 放送情報記録
	itemData[guid]['pubdate'] = new Date( pubdate.replace(/^.*?, (\d+) (.+) (\d+) (\d+:\d+:\d+) .*?$/, "$2 $1, $3 $4") );
	itemData[guid]['category'] = category;
	itemData[guid]['community_id'] = community_id;
	itemData[guid]['type'] = type;
	itemData[guid]['owner_name'] = owner_name;
	itemData[guid]['title'] = title;
    
    
    
    //HTML作成
    var row = $('<div id="'+guid+'" class="article">').hide();
    
    var rObj = new RegExp("\\b"+community_id+"\\b","i");
    
    $(row).append('<div class="thumbnail"><img src="http://icon.nicovideo.jp/community/'+community_id+'.jpg"></a>')
    
    var anchor = $('<a href="'+link+'" class="articlehead" target="_blank">').click(function(){
        widget.openURL(link);
        return false;
    });
    
    $(anchor).append('<div class="subject">'+title+'</div>');
    $(anchor).append('<span class="date">'+formatTime( itemData[guid].pubdate )+'</span>');
    $(anchor).append('<span class="timer">'+atTimer(guid)+'</span>');
    $(anchor).append('<span class="category">'+category+'</span>');
    $(anchor).append('<span class="owner_name"><strong>'+owner_name+'</strong>さん</span>');
    $(anchor).append('<div class="articlebody">'+description+'</div>');
    $(anchor).append('<div class="endline"><div></div></div>');
    
    $(row).append(anchor);
    
    addContentToRow( row, guid );
    
    
    // 現在のカテゴリと一致している放送の場合表示する
    if ( thisRowView == 1 ){
        $('#'+guid).slideDown('fast',function(){
            rsa();
        });
    }
    
}



// 
// Function : addContentToRow ( row, guid )
// 引数のjQueryオブジェクトを #content の適切な場所へ表示させます。
// 
// row : jQueryオブジェクト
// guid : lv番号
// 

function addContentToRow ( row, guid ){
	
	if ( $('#content > div').length == 0 ){
		
    	$(row).appendTo('#content');
    	
    }else{
		
		var viewd = 0;
		
	    $('#content > div').each(function(){
            
	    	var nowid = $(this).attr('id');
	    	var nowdate = itemData[nowid].pubdate.getTime();
	    	var rowdate = itemData[guid].pubdate.getTime();
	    	
	    	if( nowdate < rowdate ){
		    	$('#'+nowid).before(row);
			    viewd = 1;
		    	return false;
		    }
            
	    });
	    
	    if ( viewd == 0 ){
	    	$(row).appendTo('#content');
	    }
    }
    
}



/* ==========================================================================================
　表示の切り替え
========================================================================================== */

//
// Function : setTabAction()
// レフトナビのクリック時のアクションをセットする
//

function setTabAction(){
    $("#leftNavi .leftNavi_Row").click(function(){
        $(this).changeTab();
    })
}

// 
// Function : changeTab()
// 表示するカテゴリを変更
// 

jQuery.fn.extend({
    changeTab: function(){
        return this.each(function(){
        	
        	// カテゴリリストの表示切り替え
        	$("#leftNavi li").removeClass("now");
        	$(this).addClass("now");
        	
        	var category = $(this).find(".label").text(); //カテゴリ名
        	
        	if( nowViewCategory != category ){
	            nowViewCategory = category;
	            
	            // 非表示化実行
	            $("#contentarea").slideUp('fast',function(){
	                
	                if ( nowViewCategory == "すべて" ){
	                    
	                    $("#content > div").show();
	                    
	                }else if ( categoryList[nowViewCategory] != undefined ){
	                    
                        $("#content > div:visible").hide();
	                    var list = categoryList[nowViewCategory].split(",");
	                    
	                    for(i in list){
	                        if(list[i].length != 0){
	                            $("#"+list[i]).show();
	                        }
	                    }
	                    
	                }else{
                    
                        $("#content > div:visible").hide();
	                    
	                }
	            });
                
	            $("#contentarea").slideDown(function(){rsa();});
            }
        });
    }
});



/* ==========================================================================================
　その他
========================================================================================== */

// 
// Function : rsa
// refreshScrollAreaを実行します
// 
function rsa(){
    clearTimeout( rsaTime );
    rsaTime = setTimeout( "refreshScrollArea();", 300 );
}


// 
// Function : openToAMBS
// Apple/Macintosh放送局のブログを開きます。
// 

function openToAMBS(){
    widget.openURL('http://nicolivemac.wordpress.com/download/n2lchecker/');
}



//
// growlPost(title, comment)
// Growlへの通知を行います。
// 
// title : 
// comment : 
//

function growlPost(title, comment){
    N2LC_growlTitle = textEscape(title);
    N2LC_growlComment = textEscape(comment);
    //console.debug( "Title "+N2LC_growlTitle );
    //console.debug( "Comment "+N2LC_growlComment );
    setTimeout( function(){ widget.system("/usr/bin/osascript growl.scpt "+N2LC_growlTitle+" "+N2LC_growlComment); }, 0 );
}


//
// textEscape( text )
// 文字列をエスケープします（コマンドライン用）
// 
// text : エスケープ対象の文字列
//

function textEscape( text ){
	text = text.replace(/(!|\?|#|\$|%|&|\*|\[|\]|=|;|<|>|~|`|\\|\(|\s|\)|\||"|'|\|)/g,"\\$1");
	
	return text
}


//
// Function : formatTime( date )
// 
// date : 日付オブジェクト
// 

function formatTime( date ){
    var h = date.getHours();
    var m = date.getMinutes();
    //var s = date.getSeconds();
    if (h<10){h="0"+h;}
    if (m<10){m="0"+m;}
    //if (s<10){s="0"+s;}
    
    return h+':'+m
}


// 
// Function : at_timer( guid )
// 残りの放送時間を返す 
//
// guid : lvID
// 

function atTimer( guid ){
	var startDate = itemData[guid].pubdate;
	var startSec = startDate.getTime();
	
	var nowDate = new Date();
	var nowSec = nowDate.getTime();
	
	var endSec = startSec + 1800000;
	
	var atTimeSec = endSec - nowSec;
	
	var m = Math.floor(atTimeSec / 60000 )
	var s = Math.floor((atTimeSec - m * 60000)/1000);
		
	
    if (m<10 && m>0 ){m="0"+m;}
    if (s<10 && s>0 ){s="0"+s;}
	
	return "@"+m+":"+s
}

// 
// Function : atTimeUpdate()
// 残り時間の表示を更新
// 

function atTimeUpdate(){
	
	$(".article").each(function(){
		
		var guid = $(this).attr("id");
		var time = atTimer(guid);
		
		$(this).find(".timer").text(time);
		
	})
	
}


// 
// Function : atTimeUpdate()
// 800枠以上古いデータを削除
// 

function oldDelete(){
	
	var cssObj = {
		height:"0",
		margin:"0",
		padding:"0",
	}
	$(".article:gt(800)").css(cssObj).empty();
	
}

// 
// Function : fnFalse()
// falseを返すだけのfunction
// 

function fnFalse(){
    return false;
}
